﻿using SimpleCrawler.DAL;
using SimpleCrawler.DependencyInjection;
using SimpleCrawler.Entity;
using System;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Microsoft.Extensions.DependencyInjection;
using System.Threading;
using System.Net;
using System.Collections;

namespace SimpleCrawler.Crawler
{
    public class SouGouCrawler : CrawlerBase
    {      
        CrawlerDAL dal;  
        public SouGouCrawler():base(1004,"搜狗问问") {   
            dal = AppServiceProvider.ServiceProvider.GetService<CrawlerDAL>();
            this.RequireCookie = true;
            CookieContainer = new CookieContainer();
        }

        public override void GetStartedPageUrl()
        {
            RequestUrl = $"https://www.sogou.com/sogou?query={System.Web.HttpUtility.UrlEncode(CrawlerTask.KeyWord)}&insite=wenwen.sogou.com&tro=on";
        }
        public override void GetNextPageUrl(int page)
        {
            RequestUrl = $"https://www.sogou.com/sogou?query={System.Web.HttpUtility.UrlEncode(CrawlerTask.KeyWord)}&insite=wenwen.sogou.com&page={page}&tro=on";
        }

        //public override async Task<string> GetTargetHtmlString()
        //{
        //    await SendRequestByGetWithoutHtml("https://pb.sogou.com/cl.gif",null,true);
        //    CookieContainer.Add(new Cookie("com_sohu_websearch_ITEM_PER_PAGE", "20", "/", ".sougou.com"));
        //    return await base.GetTargetHtmlString();
        //}

        public async override Task<int> GetResultContent(string html)
        {
            Match table = Regex.Match(html, @"<div class=""results""[\s\S]*?<div class=""right"" id=""right""");
            MatchCollection trlist = Regex.Matches(table.ToString(), @"<div class=""vrwrap"">[\s\S]*?</div>[\s]</div>");
            Regex fakeReg = new Regex(@"<a target=""_blank"" href=""([\s\S]*?)"" id=");

            Regex realUrlReg = new Regex(@"window.location.replace\(""([\S]*?)""\)");

            Regex sectionReg = new Regex(@"<div class=""section""[\s\S]*?<div class=""section");
            Regex titleReg = new Regex(@"id=""question_title_val""[\s\S]*?>([\s\S]*?)</span>");
            Regex descriptionReg = new Regex(@"class=""detail-tit-info""[\s\S]*?>([\s\S]*?)</pre>");
            Regex qDateReg = new Regex(@"<div class=""user-txt""[\s\S]*?(\d{4}-\d{2}-\d{2}|\d{4}.\d{2}.\d{2})");

            Regex bestAnswer = new Regex(@"id=""bestAnswers""[\s\S]*?class=""comment-wrap");
            Regex contentReg = new Regex(@"<pre class=""replay-info-txt answer_con""[\s\S]*?>([\s\S]*?)</pre>");
            Regex zanReg = new Regex(@"up-tag like_num[\s\S]*? <em[\s\S]*?>([\s\S]*?)</em>");
            Regex caiReg = new Regex(@"down-tag unlike_num[\s\S]*?<em[\s\S]*?>([\s\S]*?)</em>");

            Regex otherAnswers = new Regex(@"class=""replay-wrap common_answers""[\s\S]*?id=""relates_box""");
            Regex otherAnswer = new Regex(@"class=""replay-section answer_item[\s\S]*?class=""comment-wrap");

            List<WD_Question> questions = new List<WD_Question>();
            if (trlist.Count > 0)
            {
                foreach (var tr in trlist)
                {
                    Match Mtitle = fakeReg.Match(tr.ToString());
                    if (Mtitle.Success)
                    {
                        string url= "https://www.sogou.com"+Mtitle.Groups[1].ToString().Trim();
                        string detailHtml=await SendRequestByGet(url);
                        Thread.Sleep(1 * 1000);
                        Match realUrl = realUrlReg.Match(detailHtml);
                        if (realUrl.Success)
                        {
                            WD_Question question = new WD_Question();
                            url = realUrl.Groups[1].ToString().Trim();
                            //url过滤
                            if (Filter!=null &&Filter.Contains(url))
                            {
                                Logger.Error($"已过滤的问答,link=>{url}");
                                FilterCount++;
                                continue;
                            }
                            Filter.Add(url);
                            //
                            Hashtable heads = new Hashtable();
                            heads.Add("Referer", "");
                            detailHtml = await SendRequestByGet(url, heads);
                            Thread.Sleep(10 * 1000);
                            Match Mquestion = sectionReg.Match(detailHtml);
                            if (Mquestion.Success)
                            {
                                try
                                {
                                    question.SourceSite = this.CrawlerID;
                                    question.KeyWord = this.CrawlerTask.KeyWord;
                                    question.SourceUrl = url;
                                    question.Question = titleReg.Match(Mquestion.ToString()).Groups[1].ToString();
                                    question.CreateTime = DateTime.Parse(qDateReg.Match(Mquestion.ToString()).Groups[1].ToString());
                                    //question.Description = descriptionReg.Match(Mquestion.ToString()).Groups[1].ToString();                                   
                                }
                                catch(Exception ex)
                                {
                                    Logger.Error($"问题匹配出错,link=>{url} {ex.ToString()}");
                                }
                                if (string.IsNullOrEmpty(question.Question)||question.CreateTime==null)
                                    continue;
                            }
                            else
                            {
                                continue;
                            }
                            question.Answers = new List<WD_Answer>();
                            Match MbestAnswer = bestAnswer.Match(detailHtml);
                            if (MbestAnswer.Success)
                            {
                                WD_Answer answer = new WD_Answer();
                                try
                                {
                                    answer.IsAdopt = 1;
                                    answer.Answer = contentReg.Match(MbestAnswer.ToString()).Groups[1].ToString();
                                    answer.AnswerLen = answer.Answer.Length;
                                    answer.CreateDate = DateTime.Parse(qDateReg.Match(MbestAnswer.ToString()).Groups[1].ToString());
                                    answer.ZanCount = int.Parse(zanReg.Match(MbestAnswer.ToString()).Groups[1].ToString());
                                    answer.CaiCount = int.Parse(caiReg.Match(MbestAnswer.ToString()).Groups[1].ToString());    
                                }
                                catch (Exception ex)
                                {
                                    Logger.Error($"最佳答案匹配出错,link=>{url} {ex.ToString()}");
                                }
                                if (!string.IsNullOrEmpty(answer.Answer))
                                {
                                    question.Answers.Add(answer);
                                }
                            }
                            MatchCollection MotherAnswers = otherAnswer.Matches(otherAnswers.Match(detailHtml).ToString());
                            foreach (Match item in MotherAnswers)
                            {
                                WD_Answer answer = new WD_Answer();
                                try
                                {
                                    answer.Answer = contentReg.Match(item.ToString()).Groups[1].ToString();
                                    answer.AnswerLen = answer.Answer.Length;
                                    answer.CreateDate = DateTime.Parse(qDateReg.Match(item.ToString()).Groups[1].ToString());
                                    answer.ZanCount = int.Parse(zanReg.Match(item.ToString()).Groups[1].ToString());
                                    answer.CaiCount = int.Parse(caiReg.Match(item.ToString()).Groups[1].ToString());
                                }
                                catch (Exception ex)
                                {
                                    Logger.Error($"最新答案匹配出错,link=>{url} {ex.ToString()}");
                                }
                                if (!string.IsNullOrEmpty(answer.Answer))
                                {
                                    question.Answers.Add(answer);
                                }
                            }
                            if (question.Answers.Count == 0)
                                Logger.Error($"未匹配到答案,link=>{url}");
                            questions.Add(question);
                        }
                        else
                        {
                            continue;
                        }
                    }
                    else
                    {
                        continue;
                    }     
                }
            }

            if (FilterCount > 0 && trlist.Count == FilterCount)
            {
                FilterCount = 0;
                return -1;
            }

            FilterCount = 0;
            if (questions.Count > 0)
            {
                var result = await SaveToDB(questions);
                if (questions.Count > 0 && (questions[questions.Count - 1].CreateTime?.CompareTo(DateTime.Now.AddMonths(-1)) ?? 1) > 0)
                {
                    CrawlerTask.EndPage = CrawlerTask.StartPage + 1;
                }
                if (!string.IsNullOrEmpty(result.Content))
                {
                    Logger.Error(result.Content);
                }
                return result.Count;
            }
            return 0;
        }

        protected async Task<(int Count, string Content)> SaveToDB(List<WD_Question> list)
        {
            return await dal.AddQuestions(list).ConfigureAwait(continueOnCapturedContext:false) ;
        }
    }
}
